import os
import base64
from datetime import datetime
from werkzeug.utils import secure_filename
from flask import Flask, render_template,redirect ,request, jsonify, session, send_file
import pandas as pd
import numpy as np
import matplotlib
matplotlib.use('Agg')  # 使用非交互式后端
import matplotlib.pyplot as plt
import seaborn as sns
from utils.data_processor import DataProcessor
from utils.chart_generator import ChartGenerator
from utils.file_handler import FileHandler

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False

app = Flask(__name__)
app.secret_key = 'personal_data_dashboard_2025'
app.config['UPLOAD_FOLDER'] = 'uploads'
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024  # 16MB 文件大小限制

# 确保上传目录存在
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
os.makedirs('exports', exist_ok=True)

# 初始化工具类
data_processor = DataProcessor()
chart_generator = ChartGenerator()
file_handler = FileHandler()

@app.route('/')
def index():
    """主页"""
    return render_template('index.html')

@app.route('/upload', methods=['POST'])
def upload_file():
    """处理文件上传"""
    try:
        if 'file' not in request.files:
            return jsonify({'error': '未选择文件'}), 400
        
        file = request.files['file']
        if file.filename == '':
            return jsonify({'error': '未选择文件'}), 400
        
        if not file_handler.allowed_file(file.filename):
            return jsonify({'error': '仅支持 CSV 文件'}), 400
        
        # 保存文件
        filename = secure_filename(file.filename)
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
        filename = f"{timestamp}_{filename}"
        filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
        file.save(filepath)
        
        # 读取并分析数据
        df = pd.read_csv(filepath, encoding='utf-8')
        
        # 限制数据大小（前1000行用于预览）
        preview_df = df.head(1000) if len(df) > 1000 else df
        
        # 分析数据
        analysis = data_processor.analyze_dataset(df)
        
        # 存储到 session
        session['current_file'] = filename
        session['data_info'] = {
            'total_rows': len(df),
            'total_cols': len(df.columns),
            'filename': file.filename,
            'upload_time': datetime.now().isoformat()
        }
        
        return jsonify({
            'success': True,
            'filename': filename,
            'data_info': session['data_info'],
            'preview': preview_df.head(10).to_html(classes='table table-striped', table_id='data-preview'),
            'analysis': analysis,
            'columns': df.columns.tolist()
        })
        
    except Exception as e:
        return jsonify({'error': f'文件处理失败: {str(e)}'}), 500

@app.route('/dashboard')
def dashboard():
    """仪表板页面"""
    if 'current_file' not in session:
        return redirect('/')
    return render_template('dashboard.html', data_info=session.get('data_info', {}))

@app.route('/api/data-info')
def get_data_info():
    """获取当前数据信息"""
    if 'current_file' not in session:
        return jsonify({'error': '未上传数据'}), 400
    
    try:
        filepath = os.path.join(app.config['UPLOAD_FOLDER'], session['current_file'])
        df = pd.read_csv(filepath)
        analysis = data_processor.analyze_dataset(df)
        
        return jsonify({
            'data_info': session['data_info'],
            'analysis': analysis,
            'preview': df.head(10).to_html(classes='table table-striped')
        })
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/api/generate-chart', methods=['POST'])
def generate_chart():
    """生成图表"""
    if 'current_file' not in session:
        return jsonify({'error': '未上传数据'}), 400
    
    try:
        data = request.get_json()
        chart_type = data.get('chart_type')
        x_column = data.get('x_column')
        y_column = data.get('y_column')
        
        filepath = os.path.join(app.config['UPLOAD_FOLDER'], session['current_file'])
        df = pd.read_csv(filepath)
        
        # 生成图表
        chart_data = chart_generator.generate_chart(
            df, chart_type, x_column, y_column
        )
        
        return jsonify(chart_data)
        
    except Exception as e:
        return jsonify({'error': f'图表生成失败: {str(e)}'}), 500

@app.route('/api/export-chart', methods=['POST'])
def export_chart():
    """导出图表"""
    try:
        data = request.get_json()
        chart_base64 = data.get('chart_data')
        format_type = data.get('format', 'png')
        
        # 解码 base64 图片
        image_data = base64.b64decode(chart_base64.split(',')[1])
        
        # 生成文件名
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
        filename = f'chart_{timestamp}.{format_type}'
        filepath = os.path.join('exports', filename)
        
        # 保存文件
        with open(filepath, 'wb') as f:
            f.write(image_data)
        
        return send_file(filepath, as_attachment=True, download_name=filename)
        
    except Exception as e:
        return jsonify({'error': f'导出失败: {str(e)}'}), 500

@app.route('/api/statistics')
def get_statistics():
    """获取统计信息"""
    if 'current_file' not in session:
        return jsonify({'error': '未上传数据'}), 400
    
    try:
        filepath = os.path.join(app.config['UPLOAD_FOLDER'], session['current_file'])
        df = pd.read_csv(filepath)
        
        stats = data_processor.generate_statistics(df)
        return jsonify(stats)
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.errorhandler(413)
def too_large(e):
    return jsonify({'error': '文件过大，请上传小于16MB的文件'}), 413

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)